﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; 
using FastReport;
using System.IO;
using System.Windows.Controls.Primitives;
using System.Windows.Media;

namespace DoubleH.Utility.Print
{
    public partial class PrintForm : Form
    {
        public PrintForm()
        {
            InitializeComponent();
        }

        public void Init(DataSet ds, string frdFile, string defaultPrintFile)
        {
            Report report = new Report();
            report.Preview = previewControl1;
            try
            {
                report.Load(frdFile);
                previewControl1.Report.RegisterData(ds);
                previewControl1.Report.Show();
            }
            catch
            {
                try
                {
                    if (string.IsNullOrEmpty(defaultPrintFile))
                        return;

                    report.Load(defaultPrintFile);
                    previewControl1.Report.RegisterData(ds);
                    previewControl1.Report.Show();
                }
                catch
                {
                    MessageWindow.Show(frdFile + " 不匹配");
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="table"></param>
        /// <param name="frdFile">必须是完整的文件路径</param>
        /// <param name="preview"></param>
        public static void ShowPrint(FCNS.Data.Interface.IDataTable table, string frdFile, bool preview = true)
        {
            System.Diagnostics.Debug.Assert(table != null);
            if (FCNS.Data.Table.SysConfig.SysConfigParams.PrintAfterSaveOrder && table.Id == -1)
            {
                DoubleH.Utility.MessageWindow.Show("请保存单据");
                return;
            }

            if (preview)
            {
                PrintForm pf = new PrintForm();
                pf.Init(GetDataSet(table), frdFile, string.Empty);
                pf.ShowDialog();
            }
            else
            {
                try
                {
                    Report report = new Report();
                    report.Load(frdFile);
                    report.RegisterData(GetDataSet(table));
                    report.PrintSettings.ShowDialog = false;
                    report.Print();
                }
                catch
                {
                    MessageWindow.Show("打印模板加载异常");
                }
            }
        }

        public static void ShowPrint(FCNS.Data.Interface.IDataTable table, DoubleH.Utility.DataTableText tableText, string defaultPrintFile)
        {
            System.Diagnostics.Debug.Assert(table != null);
            if (FCNS.Data.Table.SysConfig.SysConfigParams.PrintAfterSaveOrder && table.Id == -1)
            {
                DoubleH.Utility.MessageWindow.Show("请保存单据");
                return;
            }

            DoubleH.Utility.Configuration.PrintConfig config = DoubleH.Utility.Configuration.DoubleHConfig.AppConfig.PrintConfigItems.Find(f => f.TableText == tableText.ToString());
            string file = GetTempleteFile(tableText.ToString(), config, defaultPrintFile);
            if (!ExistsFile(file, config))
                return;

            if (table != null)
                ShowPrint(table, file);
            else
            {
                PrintForm pf = new PrintForm();
                pf.Init(GetDataSet(table), file, defaultPrintFile);
                pf.ShowDialog();
            }
        }

        public static void ShowPrint(System.Windows.Controls.DataGrid grid, DoubleH.Utility.DataTableText tableText, string defaultPrintFile)
        {
            System.Diagnostics.Debug.Assert(grid != null);
            DoubleH.Utility.Configuration.PrintConfig config = DoubleH.Utility.Configuration.DoubleHConfig.AppConfig.PrintConfigItems.Find(f => f.TableText == tableText.ToString());
            string file = GetTempleteFile(tableText.ToString(), config, defaultPrintFile);
            if (!ExistsFile(file, config))
                return;

            DataSet ds = new DataSet();
            DataTable dt = new DataTable("TableList");
            ds.Tables.Add(dt);
            int count = grid.Columns.Count;
            for (int i = 0; i < count; i++)
            {
                DataColumn ndc = new DataColumn("TableList" + i, typeof(string));
                dt.Columns.Add(ndc);
            }
            foreach (object item in grid.Items)
            {
                DataRow row = dt.NewRow();
                for (int i = 0; i < count; i++)
                {
                    System.Windows.Controls.TextBlock tb = grid.Columns[i].GetCellContent(item) as System.Windows.Controls.TextBlock;
                    if (tb == null)
                        row[i] = string.Empty;
                    else
                        row[i] = tb.Text;
                }
                dt.Rows.Add(row);
            }

            PrintForm pf = new PrintForm();
            pf.Init(ds, file, defaultPrintFile);
            pf.ShowDialog();
        }

        public static void ShowPrintList(System.Windows.Controls.DataGrid grid)
        {
            System.Diagnostics.Debug.Assert(grid != null);
            string file = FCNS.Data.DbDefine.printDir + "其它\\列表.frx";
            if (!File.Exists(file))
                return;

            DataSet ds = new DataSet();
            DataTable dt = new DataTable("TableList");
            ds.Tables.Add(dt);
            int count = grid.Columns.Count;
            for (int i = 0; i < count; i++)
            {
                DataColumn ndc = new DataColumn("TableList" + i, typeof(string));
                dt.Columns.Add(ndc);
            }
            foreach (object item in grid.Items)
            {
                DataRow row = dt.NewRow();
                for (int i = 0; i < count; i++)
                {
                    System.Windows.Controls.TextBlock tb = grid.Columns[i].GetCellContent(item) as System.Windows.Controls.TextBlock;
                    if (tb == null)
                        row[i] = string.Empty;
                    else
                        row[i] = tb.Text;
                }
                dt.Rows.Add(row);
            }

            PrintForm pf = new PrintForm();
            pf.Init(ds, file, string.Empty);
            pf.ShowDialog();
        }

        public static void ShowPrint(DataSet ds, DoubleH.Utility.DataTableText tableText, string defaultPrintFile)
        {
            System.Diagnostics.Debug.Assert(ds != null);
            
            DoubleH.Utility.Configuration.PrintConfig config = DoubleH.Utility.Configuration.DoubleHConfig.AppConfig.PrintConfigItems.Find(f => f.TableText == tableText.ToString());
            string file = GetTempleteFile(tableText.ToString(), config, defaultPrintFile);
            if (!ExistsFile(file, config))
                return;

                PrintForm pf = new PrintForm();
                pf.Init(ds, file,FCNS.Data.DbDefine.printDir+ defaultPrintFile);
                pf.ShowDialog();
        }

        public static void PrintPosPrinter(FCNS.Data.Interface.IDataTable order,string frxFile)
        {
            System.Diagnostics.Debug.Assert(order != null);
            try
            {
                Report report = new Report();
                report.Load(frxFile);
                report.RegisterData(GetDataSet(order));
                report.PrintSettings.ShowDialog = false;
                foreach (DoubleH.Utility.Configuration.PrinterCountConfig pcc in DoubleH.Utility.Configuration.DoubleHConfig.AppConfig.PrinterCount)
                {
                    for (int i = 0; i < pcc.PrintCount; i++)
                    {
                        report.PrintSettings.Printer = pcc.PrinterName;
                        report.Print();
                    }
                }
            }
            catch
            {
                MessageWindow.Show("打印模板加载异常");
            }
        }


        private static string GetTempleteFile(string dataTableTextName, DoubleH.Utility.Configuration.PrintConfig config, string defaultTempleteFile = null)
        {
            if (config == null)
            {
                DoubleH.Utility.Configuration.DoubleHConfig.AppConfig.PrintConfigItems.Add(config = new Configuration.PrintConfig() { TableText = dataTableTextName });
                if (string.IsNullOrEmpty(defaultTempleteFile))
                    config.FileName = "其它\\列表.frx";
                else
                    config.FileName = defaultTempleteFile;
            }

            return FCNS.Data.DbDefine.printDir + config.FileName;
        }

        private static bool ExistsFile(string fileName, DoubleH.Utility.Configuration.PrintConfig config)
        {
            if (!File.Exists(fileName))
            {
                MessageWindow.Show(fileName + "打印格式丢失");
                PrintConfig cf = new PrintConfig();
                cf.Init(config);
                cf.ShowDialog();
                return false;
            }
            return true;
        }

        private static DataSet GetDataSet(FCNS.Data.Interface.IDataTable table)
        {
            DataSet ds = new DataSet();
            ds.Tables.AddRange(GetDataTable(table));
            ds.Tables.AddRange(GetDataTable(FCNS.Data.Table.SysConfig.SysConfigParams));

            return ds;
        }

        public static DataTable[] GetDataTable(FCNS.Data.Interface.IDataTable table)
        {
            List<DataTable> allTable = new List<System.Data.DataTable>();
            DataTable tableOK = new DataTable();
            tableOK.TableName = table.TableName; // 一定要设置表名称
            allTable.Add(tableOK);

            AddColumns(table, tableOK, allTable);
            AddRows(table, tableOK);

            return allTable.ToArray();
        }
        /*
         * 例如销售单Table里面会有个List<ProductS>的属性
         * 这里的作用就是把List<>属性转换成Table
         */
        private static DataTable GetDataTable(System.Collections.IList obj)
        {
            if (obj == null||obj.Count==0)
                return null;

            DataTable tableOK = new DataTable();
            FCNS.Data.Interface.IDataTable table = obj[0] as FCNS.Data.Interface.IDataTable;
            if (table == null)
                return null;

            tableOK.TableName = table.TableName; // 一定要设置表名称

            AddColumns(table, tableOK, null);
            for (int i = 0; i < obj.Count; i++)
                AddRows(obj[i] as FCNS.Data.Interface.IDataTable, tableOK);

            return tableOK;
        }

        private static void AddColumns(FCNS.Data.Interface.IDataTable table, DataTable tableOK, List<DataTable> allTable)
        {
            foreach (System.Reflection.PropertyInfo info in table.GetType().GetProperties())
            {
                if (info.Name == "TableName")
                    continue;

                if (info.PropertyType.IsGenericType)
                {
                    Type t = info.PropertyType.GetGenericArguments()[0];
                    if (t.IsPrimitive || t == typeof(DateTime))
                        tableOK.Columns.Add(info.Name, info.PropertyType.GetGenericArguments()[0]);
                    else if (allTable != null)
                        allTable.Add(GetDataTable(info.GetValue(table, null) as System.Collections.IList));
                }
                else
                    tableOK.Columns.Add(info.Name, info.PropertyType);
            }
        }

        private static void AddRows(FCNS.Data.Interface.IDataTable table, DataTable tableOK)
        {
            DataRow row = tableOK.NewRow();
            foreach (DataColumn dc in tableOK.Columns)
            {
                System.Reflection.PropertyInfo info = table.GetType().GetProperty(dc.ColumnName);
                System.Diagnostics.Debug.Assert(info != null, dc.ColumnName);

                if (info.Name == "TableName")
                    continue;
                try
                {
                    object ok = info.GetValue(table, null);
                    if (ok == null)
                        row[info.Name] = DBNull.Value;
                    else
                        row[info.Name] = ok;
                }
                catch (Exception eee)
                {
                    MessageBox.Show(info.Name + "  " + info.PropertyType.ToString() + "  " + eee.Message);
                }
            }
            tableOK.Rows.Add(row);
        }
    }
}